package com.origin.bluetooth

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.util.Log
import com.origin.baselibrary.expand.MutableListLiveData
import com.origin.baselibrary.viewmodel.BaseViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import java.util.*
import android.R.attr.name
import android.R.attr.name
import android.nfc.NfcAdapter.getDefaultAdapter
import androidx.databinding.ObservableField
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import android.R.attr.name
import android.R.attr.name
import android.R.attr.name
import java.io.*
import android.R.attr.name
import android.R.attr.name
import android.bluetooth.*
import java.nio.charset.StandardCharsets


class BlueToothViewModel : BaseViewModel() {

    var logInfo = ObservableField<String>()
    val serviceUUID = "0000ffe0-0000-1000-8000-00805f9b34fb"
    var bluetoothDeviceList: MutableListLiveData<BluetoothDevice> = MutableListLiveData()
    var bluetooth4Adapter: BluetoothAdapter? = null

    // region  检测手机是否支持4.0蓝牙
    // @param context  上下文
    // @return true--支持4.0  false--不支持4.0
    fun checkBle(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {  //API 18 Android 4.3
            val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
            bluetooth4Adapter = bluetoothManager.adapter //BLUETOOTH权限
            bluetooth4Adapter != null
        } else {
            false
        }
    }
    // endregion

    // region  蓝牙是否开启
    fun isBlueToothEnable(): Boolean {
        if (bluetooth4Adapter == null) {
            return false;
        }
        return bluetooth4Adapter?.isEnabled ?: false
    }
    // endregion

    // region 蓝牙扫描回调
    var isScanRegister = false;
    private fun init(context: Context) {
        if (isScanRegister) {
            return
        }

        val filterFound = IntentFilter(BluetoothDevice.ACTION_FOUND);
        context.registerReceiver(mReceiver, filterFound);

        val filterStart = IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        context.registerReceiver(mReceiver, filterStart);

        val filterFinish = IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        context.registerReceiver(mReceiver, filterFinish);



        isScanRegister = true

    }

    private val mReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                BluetoothAdapter.ACTION_DISCOVERY_STARTED -> {
                    Log.d("BlueToothViewModel", "开始扫描");
                }
                BluetoothDevice.ACTION_FOUND -> {
                    val device: BluetoothDevice? = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                    if (device != null && !bluetoothDeviceList.contains(device)) {

                        bluetoothDeviceList.addItem(device)
                    }
                }
                BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
                    Log.d("BlueToothViewModel", "扫描结束");
                }
            }
        }

    }
    // endregion

    // region 开始蓝牙扫描

    fun startDiscoveryDevice(context: Context, timeMillis: Long = 10000) {
        if (bluetooth4Adapter == null) {
            return
        }
        val bluetoothManager =
            context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager;
        val adapter = bluetoothManager.adapter
        bluetoothDeviceList.addAll(adapter.bondedDevices)
        init(context);
        viewModelSuspend {
            delay(timeMillis)
            bluetooth4Adapter?.cancelDiscovery()
        }
        bluetooth4Adapter?.startDiscovery()
    }

    // endregion

    //region 蓝牙匹配

    private val pinBlueReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) ?: return
            if (BluetoothDevice.ACTION_PAIRING_REQUEST == action) {

            } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED == action) {
                when (device.bondState) {
                    BluetoothDevice.BOND_NONE -> {
                        viewModelScope.launch {
                            logInfo.set("取消配对")
                        }
                    }
                    BluetoothDevice.BOND_BONDING -> {
                        viewModelScope.launch {
                            logInfo.set("配对中")
                        }
                    }
                    BluetoothDevice.BOND_BONDED -> {
                        viewModelScope.launch {
                            logInfo.set("配对成功")
                        }
                        connectBluetoothServer(device, context);
                    }
                }

            }
        }
    }

    var isPinRegister = false;
    private fun initPin(context: Context) {
        if (isPinRegister) {
            return
        }
        val filterRequest = IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
        context.registerReceiver(pinBlueReceiver, filterRequest);

        val filterBondStateChanged = IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        context.registerReceiver(pinBlueReceiver, filterBondStateChanged);

        isPinRegister = true
    }

    fun pin(context: Context, device: BluetoothDevice) {
        if (bluetooth4Adapter == null) {
            return
        }
        initPin(context)
        if (bluetooth4Adapter?.isDiscovering == true) {
            bluetooth4Adapter?.cancelDiscovery()
        }
        if (device.bondState == BluetoothDevice.BOND_NONE) {
            Log.d("BlueToothViewModel", "attemp to bond:" + device.name);
            try {
                val createBondMethod = device.javaClass.getMethod("createBond");
                createBondMethod.invoke(device)
            } catch (e: Exception) {
                e.printStackTrace();
                Log.e("BlueToothViewModel", "attemp to bond fail!");
            }

        } else {
            connectBluetoothServer(device, context);
        }

    }
    //endregion

    // region 建立蓝牙服务端

    private var isWaitConnection = true
    private var bluetoothServerSocket: BluetoothServerSocket? = null
    fun blueToothService(context: Context) {


        if (bluetooth4Adapter == null) {
            return
        }

        bluetoothServerSocket = bluetooth4Adapter?.listenUsingRfcommWithServiceRecord(context.packageName, UUID.fromString(serviceUUID)) ?: return;
        viewModelScope.launch {
            val that = this;
            withContext(Dispatchers.IO) {
                while (isWaitConnection) {
                    that.launch {
                        logInfo.set("蓝牙服务端成功,等待客户端连接...")
                    }
                    Log.e("123", "ab1")
                    try {
                        val socket = bluetoothServerSocket?.accept()
                        Log.e("123", "ab2")
                        if (socket != null) {
                            that.launch {
                                logInfo.set("客户端连接成功：" + socket.remoteDevice)
                            }
                            Log.e("123", "ab3")
                            bluetoothServerSocket?.close();
                            read(socket)
                        }
                    } catch (e: IOException) {
                        that.launch {
                            logInfo.set("服务端连接异常：" + e.message)
                        }
                    }


                }
            }
        }


    }

    // endregion

    // region请求连接蓝牙服务器


    private val connectBluetoothReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            if (BluetoothDevice.ACTION_ACL_DISCONNECTED == action) {
                viewModelScope.launch {
                    logInfo.set("蓝牙设备已经断开")
                }
            } else if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
                logInfo.set("蓝牙设备已经连接")
            }
        }
    }
    var istConnectBluetoothRegister = false;
    private fun initConnectBluetooth(context: Context) {
        if (istConnectBluetoothRegister) {
            return
        }
        val filterAclDisconnected = IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        context.registerReceiver(connectBluetoothReceiver, filterAclDisconnected);

        val filterAclConnected = IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
        context.registerReceiver(connectBluetoothReceiver, filterAclConnected);
        istConnectBluetoothRegister = true;
    }

    fun connectBluetoothServer(bluetoothDevice: BluetoothDevice, context: Context) {
        viewModelScope.launch {
            logInfo.set("连接服务器中")
        }
        val bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(serviceUUID)) ?: return;
        if (bluetooth4Adapter?.isDiscovering == true) {
            bluetooth4Adapter?.cancelDiscovery()
        }

        initConnectBluetooth(context)
        if (!bluetoothSocket.isConnected) {
            viewModelScope.launch {
                withContext(Dispatchers.IO) {
                    try {
                        bluetoothSocket.connect()
                        read(bluetoothSocket)
                    } catch (e: IOException) {
                        viewModelScope.launch {
                            logInfo.set("连接服务器异常：${e.message}")
                        }
                    }

                }
            }

        }
    }
    // endregion

    //https://blog.csdn.net/qq_32115439/article/details/80379262
    // https://www.jianshu.com/p/12b69fe68246
    var outputStream: OutputStream? = null
    var _bluetoothSocket: BluetoothSocket? = null

    // region 读取内容
    var isReading = true;
    private fun read(bluetoothSocket: BluetoothSocket) {
        _bluetoothSocket = bluetoothSocket;
        outputStream = _bluetoothSocket!!.outputStream
        val `in` = _bluetoothSocket!!.inputStream
        while (isReading) {
            val buffer = ByteArray(1024)
            try {
                val bytes: Int = `in`.read(buffer)
                val strString = String(buffer.copyOfRange(0, bytes), StandardCharsets.UTF_8)
                viewModelScope.launch {
                    logInfo.set("接受到的消息：${strString}")
                }
            } catch (e: IOException) {
                break
            }
        }
    }
    // endregion

    // region 发送
    fun sendMsg(msg: String) {

        outputStream?.apply {

            write(msg.toByteArray())
            flush()
            logInfo.set("发送成功$msg")
        }

    }
    // endregion

    //region 关闭
    private fun close() {
        isWaitConnection = false
        isReading = false
        bluetoothServerSocket?.close();
        _bluetoothSocket?.inputStream?.close()
        _bluetoothSocket?.outputStream?.close()
        _bluetoothSocket?.close()
    }

    override fun onCleared() {
        super.onCleared()
        close()
    }
    //endregion


}